#define FORCEGROUPBAR_CPP
/*************************************************************************************************\
ForceGroupBar.cpp			: Implementation of the ForceGroupBar component.
//---------------------------------------------------------------------------//
// Copyright (C) Microsoft Corporation. All rights reserved.                 //
//===========================================================================//
\*************************************************************************************************/

#include "ForceGroupBar.h"
#include "MechIcon.h"
#include "ObjMgr.h"
#include "Team.h"
#include "MissionGui.h"
#include "ControlGui.h"
#include "..\resource.h"
#include "multplyr.h"
#include "mc2movie.h"
#include "comndr.h"
#include "prefs.h"
#include "GameSound.h"

float ForceGroupBar::iconWidth = 48;
float ForceGroupBar::iconHeight = 42;
int	  ForceGroupBar::iconsPerRow = 8;

StaticInfo*  ForceGroupBar::s_coverIcon = NULL;

extern bool useLeftRightMouseProfile;
extern char CDInstallPath[];
void EnterWindowMode();
void EnterFullScreenMode();
void __stdcall ExitGameOS();

#define BOTTOM_OFFSET	5 * Environment.screenHeight/640.f

#define FORCEGROUP_LEFT		ForceGroupIcon::selectionRect[0].left
#define FORCEGROUP_WIDTH	(ForceGroupIcon::selectionRect[7].right - ForceGroupIcon::selectionRect[0].left)
#define FORCEGROUP_HEIGHT	(ForceGroupIcon::selectionRect[0].bottom - ForceGroupIcon::selectionRect[0].top)

extern float frameRate;
 
ForceGroupBar::ForceGroupBar()
{
	for ( int i = 0; i < MAX_ICONS; ++i )
	{
		icons[i] = 0;
	}

	iconCount = 0;

	forceNumFlashes = 0;
	forceFlashTime = 0.0f;
}

ForceGroupBar::~ForceGroupBar()
{
	removeAll();
	
	if ( ForceGroupIcon::gosFontHandle )
		delete ForceGroupIcon::gosFontHandle;

	ForceGroupIcon::gosFontHandle  = NULL;
}


bool ForceGroupBar::flashJumpers (long numFlashes)
{
	forceNumFlashes = numFlashes;
	forceFlashTime = 0.0f;

	return true;
}

bool ForceGroupBar::addMech( Mover* pMover )
{
	if ( iconCount >= MAX_ICONS )
	{
		gosASSERT( false );
		return 0;
	}
	
	MechIcon* pIcon = new MechIcon;
	bool bRetVal = pIcon->init( pMover );

	icons[iconCount++] = pIcon;
	
	return bRetVal;
}

bool ForceGroupBar::addVehicle( Mover* pMover )
{
	if ( iconCount >= MAX_ICONS )
	{
		gosASSERT( false );
		return 0;
	}
	
	VehicleIcon* pIcon = new VehicleIcon;
	bool bRetVal = pIcon->init( pMover );

	icons[iconCount++] = pIcon;

	return bRetVal;
}

void ForceGroupBar::removeMover (Mover* mover) {

	for (long i = 0; i < iconCount; i++)
		if (icons[i]->unit == mover) {
			delete icons[i];
			iconCount --;
			memmove( &icons[i], &icons[i] + 1, (iconCount - i) * sizeof (ForceGroupIcon*) );
			icons[iconCount] = 0;
			break;
		}
}

void ForceGroupBar::update( )
{
	bool bSelect = userInput->isLeftClick();
	bool bCommand = useLeftRightMouseProfile ? userInput->isRightClick() : userInput->isLeftClick();
	bool shiftDn = userInput->getKeyDown( KEY_LSHIFT ) ? true : false;
	bool bCamera = useLeftRightMouseProfile ? (userInput->isLeftDoubleClick()) : (userInput->isRightClick() && !userInput->isRightDrag());
	bool bForceGroup = useLeftRightMouseProfile ? (userInput->isLeftDoubleClick()) : userInput->isLeftDoubleClick();
	
	if ( bCamera )
		bSelect = 0;

	Stuff::Vector2DOf<long> screen;
	screen.x = userInput->getMouseX();
	screen.y = userInput->getMouseY();

	 if ( screen.x > FORCEGROUP_LEFT && screen.x < FORCEGROUP_LEFT + FORCEGROUP_WIDTH
		  && screen.y > FORCEGROUP_TOP )
	 {
		 if ( ControlGui::instance->isSelectingInfoObject() )
			userInput->setMouseCursor( mState_INFO );
		 else if ( ControlGui::instance->getRepair() )
			 userInput->setMouseCursor( mState_XREPAIR );
		 else if ( MissionInterfaceManager::instance()->hotKeyIsPressed( EJECT_COMMAND_INDEX ) )
			 userInput->setMouseCursor( mState_EJECT );
		 else
			userInput->setMouseCursor( mState_NORMAL );

		helpTextID = IDS_FORCEGROUP_BAR_DESC;
		helpTextHeaderID = IDS_FORCEGROUP_BAR;
	 }



	// unselect all if appropriate
	if ( bSelect && !shiftDn && inRegion(screen.x, screen.y) 
		&& !ControlGui::instance->isSelectingInfoObject() && (!ControlGui::instance->getRepair()
		&& !MissionInterfaceManager::instance()->hotKeyIsPressed( EJECT_COMMAND_INDEX )
		&& !ControlGui::instance->getGuard()
		|| useLeftRightMouseProfile) )
	{
		Team* pTeam = Team::home;
		for ( int i = 0; i < pTeam->rosterSize; ++i )
		{
			Mover* pMover = (Mover*)pTeam->getMover( i );
			if (pMover->getCommander()->getId() == Commander::home->getId())
			{
				pMover->setSelected( false );
			}
		}
	}

	
	// remove dead mechs
	for ( int t = 0; t < iconCount; ++t )
	{
		if ( (icons[t]->unit->isDestroyed() || icons[t]->unit->isDisabled()) && !icons[t]->unit->recoverBuddyWID )
		{
			if ( !icons[t]->isAnimatingDeath() )
				icons[t]->beginDeathAnimation();
			if ( icons[t]->deathAnimationOver() || icons[t]->unit->causeOfDeath == POWER_USED_UP )
			{
				delete icons[t];
				iconCount --;
				memmove( &icons[t], &icons[t] + 1, (iconCount - t) * sizeof (ForceGroupIcon*) );
				icons[iconCount] = 0;
			}
		}
	}

	qsort( icons, iconCount, sizeof( ForceGroupIcon* ), ForceGroupIcon::sort );

	for ( int i = 0; i < iconCount; i++ )
	{
		icons[i]->setLocationIndex( i );
	}
	

	for ( i = 0; i < iconCount; ++i )
	{
		if ( icons[i]->inRegion( screen.x, screen.y ) )
		{
			icons[i]->unit->setTargeted(true); 
			if ( ControlGui::instance->getRepair() )
			{
				if ( !MissionInterfaceManager::instance()->canRepair(icons[i]->unit ) )
				{
					userInput->setMouseCursor( mState_XREPAIR );
				
					// need to go back and unselect everything
					if ( bSelect  )
					{
						if ( !shiftDn )
						{
							Team* pTeam = Team::home;
							for ( int j = 0; j < pTeam->rosterSize; ++j )
							{
								Mover* pMover = (Mover*)pTeam->getMover( j );
								if (pMover->getCommander()->getId() == Commander::home->getId())
								{
									pMover->setSelected( false );
								}
							}
						}						
					}
				}
				else
				{
					userInput->setMouseCursor( mState_REPAIR );
				}
			}
			else if ( ControlGui::instance->getGuard() )
			{
				userInput->setMouseCursor( mState_GUARD );
			}
			else
			{
				ControlGui::instance->setRolloverHelpText( IDS_UNIT_SELECT_HELP );
			}

			if ( bSelect && !ControlGui::instance->infoButtonPressed() )
			{
				if ( !(ControlGui::instance->getRepair() && MissionInterfaceManager::instance()->canRepair(icons[i]->unit ) && !useLeftRightMouseProfile) )
					icons[i]->click( shiftDn ); 

				ControlGui::instance->setInfoWndMover( icons[i]->unit );	
			}

			if ( bCommand )
			{
				 if ( MissionInterfaceManager::instance()->hotKeyIsPressed( EJECT_COMMAND_INDEX ) )
				 {
					 MissionInterfaceManager::instance()->doEject( icons[i]->unit );
				 }
				 else if ( ControlGui::instance->getGuard() )
				 {
					 MissionInterfaceManager::instance()->doGuard( icons[i]->unit );
				 }
				 else if ( ControlGui::instance->getRepair() )
				 {
					 if ( MissionInterfaceManager::instance()->canRepair(icons[i]->unit ) )
						MissionInterfaceManager::instance()->doRepair( icons[i]->unit );
				 }
				 

				 else
					 ControlGui::instance->setInfoWndMover( icons[i]->unit );	
			}

			if ( bCamera )
			{
				icons[i]->rightClick();
			}

			if ( bForceGroup )
			{
				for( int j = 0; j < 10; ++j )
				{
					if ( icons[i]->unit->isInUnitGroup( j ) )
					{
						
						MissionInterfaceManager::selectForceGroup( j, true );

					}
				}				
			}
		
		}
		else
			icons[i]->unit->setTargeted( 0 );
		
		icons[i]->update();
		
	}

}

bool ForceGroupBar::inRegion( int x, int y )
{
	for ( int i = 0; i < iconCount; ++i )
	{
		if ( icons[i]->inRegion( x, y ) )
			return true;
	}

	return false;

}

void ForceGroupBar::render()
{	
	s_coverIcon->setColor( 0 );
		
	int maxUnits = 16;

	if ( MPlayer )
	{
		long playerCount;
		MPlayer->getPlayers( playerCount );
		if (playerCount)
			maxUnits = (MAX_MULTIPLAYER_MECHS_IN_LOGISTICS/playerCount) + 4;
		else
			maxUnits = 0;


		if ( maxUnits > 16 )
			maxUnits = 16;
	}


	for ( int i = 0; i < MAX_ICONS; i++ )
	{
		if (forceNumFlashes && icons[i] && icons[i]->unit->canJump())
		{
			if ( forceFlashTime > .25f )
			{
				if ( icons[i])
					icons[i]->render();
			}
		}
		else
		{
			if ( icons[i] )
				icons[i]->render();
		}

		if ( i >= maxUnits )
		{
			if ( s_coverIcon )
			{
				s_coverIcon->setLocation( ForceGroupIcon::selectionRect[i].left, ForceGroupIcon::selectionRect[i].top );
				s_coverIcon->setColor( 0xffffffff );
				s_coverIcon->render();
				s_coverIcon->setColor( 0 );
			}
		}
	}

	if (forceNumFlashes)
	{
		forceFlashTime += frameLength;
		if ( forceFlashTime > .5f )
		{
			forceFlashTime = 0.0f;
			forceNumFlashes--;
		}
	}
}

void ForceGroupBar::removeAll()
{
	for ( int i = 0; i < iconCount; i++ )
	{
		if ( icons[i] )
			delete icons[i];

		icons[i] = NULL;
	}

	iconCount = 0;
}

void ForceGroupBar::init( FitIniFile& file, StaticInfo* pCoverIcon )
{

	if ( NO_ERR != file.seekBlock( "Fonts" ) )
		Assert( 0, 0, "couldn't find the font block" );

	if ( !ForceGroupIcon::gosFontHandle )
		ForceGroupIcon::gosFontHandle = new aFont;

	long fontID;
	file.readIdLong( "IconFont", fontID );
	ForceGroupIcon::gosFontHandle->init( fontID );

	
	swapResolutions();

	for ( int i = 0; i < 16; i++ )
		ForceGroupIcon::init( file, i );

	s_coverIcon = pCoverIcon;
}

void ForceGroupBar::swapResolutions()
{
	ForceGroupIcon::resetResolution(0);
	
	for ( int i = 0; i < iconCount; i++ )
		icons[i]->swapResolutions(0);

	
}

bool ForceGroupBar::setPilotVideo( const char* pVideo, MechWarrior* pPilot )
{
	if ( !pVideo  )
	{
		if ( ForceGroupIcon::bMovie )
		{
			delete ForceGroupIcon::bMovie;
			ForceGroupIcon::bMovie = NULL;
			
		}
		else if ( ForceGroupIcon::pilotVideoTexture )
			gos_DestroyTexture( ForceGroupIcon::pilotVideoTexture );
		
		ForceGroupIcon::pilotVideoTexture = 0;
		ForceGroupIcon::pilotVideoPilot = 0;
	}

	else if  (ForceGroupIcon::bMovie || ControlGui::instance->isMoviePlaying()
		|| ForceGroupIcon::pilotVideoTexture || !prefs.pilotVideos)
	{
		// one already playing...
		// OR we don't want them playing.
		return 0;
	}

	else
	{
		for ( int i = 0; i < iconCount; i++ )
		{
			if ( icons[i] && icons[i]->unit->getPilot() == pPilot )
			{
				ForceGroupIcon::pilotVideoPilot = pPilot;
				FullPathFileName aviPath;
				aviPath.init( moviePath, pVideo, ".bik" );

				if ( (frameRate > 15.0) && fileExists(aviPath) && prefs.pilotVideos) // This is about correct.  Slower then this and movie has hard time keeping up!
				{
					//Update the RECT every frame.  What if we shift Icons around cause someone died!!
					RECT vRect;
					vRect.left 		= icons[i]->bmpLocation[icons[i]->locationIndex][1].x;
					vRect.right 	= icons[i]->pilotLocation[icons[i]->locationIndex][2];
					vRect.top 		= icons[i]->bmpLocation[icons[i]->locationIndex][3].y;
					vRect.bottom 	= icons[i]->bmpLocation[icons[i]->locationIndex][1].y;

					ForceGroupIcon::bMovie = new MC2Movie;
					ForceGroupIcon::bMovie->init(aviPath,vRect,true);
				}
				else // make a still texture
				{
					char realPilotName[9];

					//Set everything to zero so the strncpy below doesn't go off into LALA land!!
					memset(realPilotName,0,9);
					strncpy(realPilotName,pPilot->getName(),8);

					FullPathFileName path;
					path.init( moviePath, realPilotName, ".tga" );

					if (fileExists(path))
						ForceGroupIcon::pilotVideoTexture = gos_NewTextureFromFile( gos_Texture_Solid, path, 0 );
					else
					{
						char realMovieName[256];
						char realMoviePath[1024];
						_splitpath(path,NULL,realMoviePath,realMovieName,NULL);

						//Not in main installed directory and not in fastfile.  Look on CD.
						char actualPath[2048];
						strcpy(actualPath,CDInstallPath);
						strcat(actualPath,realMoviePath);
						strcat(actualPath,realMovieName);
						strcat(actualPath,".tga");

						bool fileThere = fileExists(actualPath);
						if (fileThere)
							ForceGroupIcon::pilotVideoTexture = gos_NewTextureFromFile( gos_Texture_Solid, actualPath, 0 );

						bool openFailed = false;
						while (!fileThere)
						{
							openFailed = true;
							EnterWindowMode();

							char data[2048];
							char msg[1024];
							char msg1[512];
							char title[256];
							cLoadString(IDS_MC2_movieMISSING,msg1,511);
							cLoadString(IDS_MC2_CDMISSING,msg,1023);
							cLoadString(IDS_MC2_MISSING_TITLE,title,255);
							sprintf(data,msg1,path,msg);
							DWORD result = MessageBox(NULL,data,title,MB_OKCANCEL | MB_ICONWARNING);
							if (result == IDCANCEL)
							{
								ExitGameOS();
								return 1; 
							}

							fileThere = fileExists(actualPath);
							if (fileThere)
								ForceGroupIcon::pilotVideoTexture = gos_NewTextureFromFile( gos_Texture_Solid, actualPath, 0 );
						}

						if (openFailed && (Environment.fullScreen == 0) && prefs.fullScreen)
							EnterFullScreenMode();
					}
				}

				break;
			}
		}
	}

	return 1;
}

bool ForceGroupBar::isPlayingVideo()
{
	if ( ForceGroupIcon::bMovie )
		return true;

	return false;
}

//*************************************************************************************************
// end of file ( ForceGroupBar.cpp )
